/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.to.aboomy.bannersample.util;

import ohos.agp.utils.Point;

/**
 * 计算贝赛尔曲线坐标的工具类
 *
 * @since 2021-08-06
 */
public class BezierUtil {
    private static final int NUM_2 = 2;
    private static final int NUM_3 = 3;

    private BezierUtil() {
    }

    /**
     * B(t1) = (1 - t1)^2 * P0 + 2t * (1 - t1) * P1 + t^2 * P2, t1 ∈ [0,1]
     *
     * @param t1 曲线长度比例
     * @param p0 起始点
     * @param p1 控制点
     * @param p2 终止点
     * @return t对应的点
     */
    public static Point calculateBezierPointForQuadratic(float t1, Point p0, Point p1, Point p2) {
        Point point = new Point();
        float temp = 1 - t1;
        float x1 = temp * temp * p0.getPointX() + NUM_2 * t1 * temp * p1.getPointX() + t1 * t1 * p2.getPointX();
        float y1 = temp * temp * p0.getPointY() + NUM_2 * t1 * temp * p1.getPointY() + t1 * t1 * p2.getPointY();
        point.modify(x1, y1);
        return point;
    }

    /**
     * B(t1) = P0 * (1-t1)^3 + 3 * P1 * t1 * (1-t1)^2 + 3 * P2 * t1^2 * (1-t1) + P3 * t1^3, t1 ∈ [0,1]
     *
     * @param t1 曲线长度比例
     * @param p0 起始点
     * @param p1 控制点1
     * @param p2 控制点2
     * @param p3 终止点
     * @return t对应的点
     */
    public static Point calculateBezierPointForCubic(float t1, Point p0, Point p1, Point p2, Point p3) {
        Point point = new Point();
        float temp = 1 - t1;
        float x1 = p0.getPointX() * temp * temp * temp + NUM_3 * p1.getPointX() * t1 * temp * temp
                + NUM_3 * p2.getPointX() * t1 * t1 * temp + p3.getPointX() * t1 * t1 * t1;
        float y1 = p0.getPointY() * temp * temp * temp + NUM_3 * p1.getPointY() * t1 * temp * temp
                + NUM_3 * p2.getPointY() * t1 * t1 * temp + p3.getPointY() * t1 * t1 * t1;
        point.modify(x1, y1);
        return point;
    }
}